package com.liao.rent.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.liao.rent.constant.ResultCode;
import com.liao.rent.dto.SysUserDto;
import com.liao.rent.entity.House;
import com.liao.rent.entity.JsonResult;
import com.liao.rent.entity.SysUser;
import com.liao.rent.entity.SysUserDetails;
import com.liao.rent.service.HouseService;
import com.liao.rent.serviceImpl.SysUserServiceImpl;
import com.liao.rent.utils.ResultTool;
import com.liao.rent.utils.WebSecurityUtils;
import com.liao.rent.vo.LoginVo;
import com.liao.rent.vo.oldAndNewPassWordVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用户表 前端控制器
 * </p>
 *
 * @author liao
 * @since 2024-11-24
 */
@Slf4j
@RestController
@Tag(name = "用户管理")
@RequestMapping("/sysUser")
public class SysUserController {

    @Autowired
    SysUserServiceImpl userService;

    @Autowired
    PasswordEncoder passwordEncoder;

    @Autowired
    HouseService houseService;


    @Autowired
    AuthenticationManager authenticationManager;


    /**
     * 获取用户信息
     * @return 返回用户的信息
     */
    @Operation(summary = "获取用户信息查询")
    @GetMapping("/getUserInfo")
    public JsonResult<SysUser>  getUserInfo(){
        JsonResult<SysUser> userInfo=  userService.getUserInfo();
        return userInfo;
    }

    /**
     * 获取用户信息
     * @return 返回用户的信息
     */
    @Operation(summary = "获取用户权限信息")
    @GetMapping("/getuserAuthorities")
    public JsonResult  getuserAuthorities(){
//        获取当前用户id
        SysUserDetails sysUserDetails = (SysUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
//        查询当前用户的权限
        List<String> userAuthorities = userService.getUserAuthorities(sysUserDetails.getUser().getId());
        return ResultTool.success(userAuthorities);
    }

    /**
     * 注册用户
     * @param sysUser
     * @return 返回注册成功的信息
     */
    @Operation(summary = "注册用户")
    @PostMapping("/regist")
    public JsonResult<String> regist(@RequestBody SysUserDto sysUser){
        Boolean flag = userService.createUser(sysUser);
        /**
         * 插入用户与角色的对应关系
         */
        userService.createRoleIdBYUserId(sysUser.getId(),sysUser.getRoleId());


        if (!flag){
            return ResultTool.fail(ResultCode.USER_ACCOUNT_ALREADY_EXIST);
        }
        return ResultTool.success("注册成功");
    }

    /**
     * 修改用户信息
     * @param sysUser
     * @return
     */
    @Operation(summary = "修改用户信息")
    @PostMapping("/update")
    public JsonResult<String> update(@RequestBody SysUserDto sysUser){
        /**
         * 判断用户修改的是不是自己的数据，否则修改
         * 管理员可以修改
         */
        SysUserDetails user = WebSecurityUtils.getUser();
//        Integer id = sysUser.getId();
//        Integer id1 = user.getUser().getId();

        if ( !sysUser.getId().equals( user.getUser().getId()) && !WebSecurityUtils.isAdmin()){
            return ResultTool.fail("无权限修改");
        }



        try {
            sysUser.setPassword(null);
            userService.updateById(sysUser);
            if (sysUser.getRoleId()!=null){
                userService.updateRoleIdBYUserId(sysUser.getId(),sysUser.getRoleId());
            }

        }catch (Exception e){
            return ResultTool.fail("修改失败");
        }

        return ResultTool.success("修改成功");
    }

    /**
     * 登录
     * @param vo 登录参数
     * @return 返回登录token字符
     */
    @Operation(summary = "登录")
    @PostMapping("login")
    public JsonResult login (@RequestBody LoginVo vo){
        JsonResult login = userService.login(vo);
        return login;
    }

    /**
     * 退出登录
     * @return 返回退出是否成功
     */
    @Operation(summary = "退出登录")
    @PostMapping("/logout")
    public JsonResult logout(){
        JsonResult logout = userService.logout();
        return logout;
    }


    /**
     * 获取用户列表
     * @param page 当前页
     * @param size 每页大小
     * @param name 账号
     * @return 返回用户列表
     */
    @Operation(summary = "获取用户列表")
    @GetMapping("/list")
    @PreAuthorize("hasAuthority('admin')")
    public JsonResult<Page<SysUserDto>> list(int page, int size, String name){
        return userService.List(page,size,name);
    }

    /**
     * 删除用户
     * @param userIds  需要删除的用户id
     * @return 是否删除成功
     */
    @Operation(summary = "删除用户")
    @PostMapping("/delete")
    @PreAuthorize("hasAuthority('admin')")
    @Transactional
    public JsonResult<String> delete(@RequestBody List<Integer> userIds){

        /**
         * 遍历查询用户是不是房东，是房东就把他的房源下架
         */
        for (Integer userId : userIds) {
            List<String> userAuthorities = userService.getUserAuthorities(userId);
            if (userAuthorities.contains("landlord")){
                //如果删除的是房东，则发布的所有房源都设置为下架状态
                LambdaQueryWrapper<House> queryWrapper=new LambdaQueryWrapper<House>();
                queryWrapper.eq(House::getUserId,userId);
                List<House> list = houseService.list(queryWrapper);
                list.stream().map(house -> {
                    house.setStatus(4);
                    return house;
                }).collect(Collectors.toList());
                houseService.updateBatchById(list);
            }
        }


        /**
         * 遍历删除用户对应的角色
         */
        for (Integer userId : userIds) {
            userService.deleteRoleIdBYUserId(userId);
        }


        boolean remove = userService.removeByIds(userIds);

        if (!remove){

            return ResultTool.fail("删除失败");
        }

        return ResultTool.success("删除成功");
    }

    /**
     *管理员修改密码
     * @param sysUser
     * @return
     */
    @Operation(summary = "管理员修改密码")
    @PostMapping("/updatePasswordById")
    @PreAuthorize("hasAuthority('admin')")
    public JsonResult<String> updatePasswordById(@RequestBody SysUser sysUser){
//        对密码进行加密
        String password = sysUser.getPassword();
        String encode ="{bcrypt}"+ passwordEncoder.encode(password);
        sysUser.setPassword(encode);

//        构建表达式
        LambdaUpdateWrapper<SysUser> updateWrapper=new LambdaUpdateWrapper<SysUser>();
        updateWrapper.eq(SysUser::getId,sysUser.getId());
        updateWrapper.set(SysUser::getPassword,sysUser.getPassword());
    //更新数据
        boolean update = userService.update(updateWrapper);
        if (!update){
            return ResultTool.fail("修改失败");
        }
        return ResultTool.success("修改成功");
    }
    @Operation(summary = "用户修改密码")
    @PostMapping("/User/updatePasswordById")
    public JsonResult<String> UserupdatePasswordById(@RequestBody  oldAndNewPassWordVO vo){
        //从安全上下文中获取用户信息
        SysUserDetails principal = (SysUserDetails) SecurityContextHolder.getContext().getAuthentication().getPrincipal();
        //判断vo是不是为空
        if (vo == null){
return ResultTool.fail("修改失败");
        }
        if (vo.getOldpassWord() == null || vo.getNewpassWord() == null){
            return ResultTool.fail("修改失败");
        }

        //在安全验证管理器中验证密码是否正确
        //        获取UsernamePasswordAuthenticationToken 创建用户密码验证token对象
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(principal.getUser().getAccount(), vo.getOldpassWord());
        try {
            //添加到验证管理器进行验证
            Authentication authRequest = authenticationManager.authenticate(authenticationToken);

            //如果旧密码正确，则修改为新密码
            if (authRequest.isAuthenticated()) {

                    SysUser sysUser = new SysUser();
                    sysUser.setPassword("{bcrypt}"+passwordEncoder.encode(vo.getNewpassWord()));
                    sysUser.setId(principal.getUser().getId());
                    boolean update = userService.updateById(sysUser);
                    if (update){
                        return ResultTool.success("修改成功");
                    }

            }
        }catch (Exception e){
            return ResultTool.fail("旧密码错误");
        }


        return ResultTool.fail("旧密码错误");
    }


    /**
     * 根据房源id查询房主的信息
     */
    @Operation(summary = "根据房源id查询房源房主的信息")
    @GetMapping("/gethouseByHouseId/{houseId}")
    public JsonResult<SysUser> gethouseByHouseId(@PathVariable(value = "houseId") Integer houseId){
        LambdaUpdateWrapper<House> houseLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        houseLambdaUpdateWrapper.eq(House::getHouseId,houseId);
        House house = houseService.getOne(houseLambdaUpdateWrapper);
        Integer userId = house.getUserId();
        SysUser sysUser = userService.getById(userId);
        sysUser.setPassword("");

      return ResultTool.success(sysUser);
    }


}
